package com.hk.commons;

import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;

/**
 * AES 算法 对称加密，密码学中的高级加密标准 2005年成为有效标准
 * 
 * @author stone
 * @date 2014-03-10 06:49:19
 */
public class AES {
	
	private static final String password = "1FC4F85242C1F81E50D01EAB47C9E8ED";
	
	//private static final String password = "1234567812345678";
	
	static Cipher cipher;
	static final String KEY_ALGORITHM = "AES";
	
	
	static final String CIPHER_ALGORITHM_ECB = "AES/ECB/PKCS5Padding";
	/* 
     *  
     */
	static final String CIPHER_ALGORITHM_CBC = "AES/CBC/PKCS5Padding";
	/*
	 * AES/CBC/NoPadding 要求 密钥必须是16位的；Initialization vector (IV) 必须是16位
	 * 待加密内容的长度必须是16的倍数，如果不是16的倍数，就会出如下异常：
	 * javax.crypto.IllegalBlockSizeException: Input length not multiple of 16
	 * bytes
	 * 
	 * 由于固定了位数，所以对于被加密数据有中文的, 加、解密不完整
	 * 
	 * 可 以看到，在原始数据长度为16的整数n倍时，假如原始数据长度等于16*n，则使用NoPadding时加密后数据长度等于16*n，
	 * 其它情况下加密数据长 度等于16*(n+1)。在不足16的整数倍的情况下，假如原始数据长度等于16*n+m[其中m小于16]，
	 * 除了NoPadding填充之外的任何方 式，加密数据长度都等于16*(n+1).
	 */
	static final String CIPHER_ALGORITHM_CBC_NoPadding = "AES/CBC/NoPadding";

	static SecretKey secretKey;

	public static void main(String[] args) throws Exception {
		String content = "{\"orderId\":\"201605050000\"}";  
		//String password = "A@#￥hk123#./()!@#$%$%^&*((^%$";  
		
		
		//String content = "Fb7gCTOporObld0d/s/1AdaVymf4tSRPA9jLQR1eLJytjW+4qtWu0ygaIMRjDSYT9uqlaQUUa3I5YUSTbikh4lUvv+P+mpVXLz+p6Cn89J72Zvz0zL5VB4E5k7AoHJErU7R5YlblTL1mvE+xI+7x73Ny9HTYDoha2FTnMn/VkDgzo0z4Xx54/q60onccjprntJiRYmEWmZmr78toHtYrQCOL+6h4ghOyxT6q5FIag3bGWaJNuG+NATcMnfeDwU/p";
		 
		String str = "f_T2wUnDG8Iwu_S1jI-1SNfkSAfzf8_0K-70F_sc1fs2VWOYtT5bBsc48fSgMgAYUD5e-8EWNYhfwwVqaasUC1KAt9X7PDdq107Ki5QvzlEOpVEUm-4Pey4q755Hz6MiuqrElRv6lRz72QRPpysjFsdQ14fmuQCBW-dxL7yMFhiiuUn45FPDxgwmN3DCzZpV4iTfbhq5o9FTB60uhL6l1Zx75BuT8B7OCrUNV9qNHFvw7cuz8OGff2pF9z42GKkA";
		//加密  
		System.out.println("加密前：" + content);  
		String encryptResult = encrypt(content); 
		
		System.out.println("加密后：" + encryptResult.length() + "  " + encryptResult); 
		 
		//解密  
		String decryptResult = decrypt(str);  
		System.out.println("解密后：" + decryptResult); 
	 
	}

	/**
	 * 
	 * @param content
	 * @param password
	 * @return
	 */
	public static String encrypt(String content) {
		try {
			byte[] keyByte = parseHexStr2Byte(password);
			      
            SecretKeySpec key = new SecretKeySpec(keyByte, KEY_ALGORITHM);  
            
            Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM_ECB);// 创建密码器  
            byte[] byteContent = content.getBytes("utf-8");  
            
            cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化  
            
            byte[] result = cipher.doFinal(byteContent);   
            
            return Base64.encodeBase64URLSafeString(result);  
			
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			e.printStackTrace();
		} catch (BadPaddingException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 解密
	 * 
	 * @param content
	 *            待解密内容
	 * @param password
	 *            解密密钥
	 * @return
	 */
	public static String decrypt(String content) {
		try {
			
			//byte[] contentByte = parseHexStr2Byte(content);
					
			//将16进制转换为2进制字符串
			
			//获取key 
			byte[] keyByte = parseHexStr2Byte(password);
            SecretKeySpec key = new SecretKeySpec(keyByte, KEY_ALGORITHM);  
            //解码base64
			byte[] decryptFrom = Base64.decodeBase64(content); 
			Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM_ECB);// 创建密码器
			cipher.init(Cipher.DECRYPT_MODE, key);
			byte[] result = cipher.doFinal(decryptFrom);
			return new String(result); // 解密
			
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			e.printStackTrace();
		} catch (BadPaddingException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**将二进制转换成16进制 
	 * @param buf 
	 * @return 
	 */ 
	public static String parseByte2HexStr(byte buf[]) {  
        StringBuffer sb = new StringBuffer();  
        for (int i = 0; i < buf.length; i++) {  
                String hex = Integer.toHexString(buf[i] & 0xFF);  
                if (hex.length() == 1) {  
                        hex = '0' + hex;  
                }  
                sb.append(hex.toUpperCase());  
        }  
        return sb.toString();  
	}
	
	/**将16进制转换为二进制 
	 * @param hexStr 
	 * @return 
	 */  
	public static byte[] parseHexStr2Byte(String hexStr) {  
        if (hexStr.length() < 1)  
                return null;  
        byte[] result = new byte[hexStr.length()/2];  
        for (int i = 0;i< hexStr.length()/2; i++) {  
                int high = Integer.parseInt(hexStr.substring(i*2, i*2+1), 16);  
                int low = Integer.parseInt(hexStr.substring(i*2+1, i*2+2), 16);  
                result[i] = (byte) (high * 16 + low);  
        }  
        return  result;  
	}  
	
	 

}
